From 1eee181e219dfd993d396ac3169e7aad3dd285eb Mon Sep 17 00:00:00 2001 From: Factiven Date: Sun, 16 Jul 2023 22:35:39 +0700 Subject: Update v3.6.4 - Added Manga page with a working tracker for AniList user - Added schedule component to home page - Added disqus comment section so you can fight on each other (not recommended) - Added /id and /en route for english and indonesian subs (id route still work in progress) --- pages/id/profile/[user].js | 423 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 423 insertions(+) create mode 100644 pages/id/profile/[user].js (limited to 'pages/id/profile/[user].js') diff --git a/pages/id/profile/[user].js b/pages/id/profile/[user].js new file mode 100644 index 0000000..6bc804e --- /dev/null +++ b/pages/id/profile/[user].js @@ -0,0 +1,423 @@ +import { getServerSession } from "next-auth"; +import { authOptions } from "../../api/auth/[...nextauth]"; +import Navbar from "../../../components/navbar"; +import Image from "next/image"; +import Link from "next/link"; +import Head from "next/head"; +import { useState } from "react"; + +export default function MyList({ media, sessions, user, time }) { + const [listFilter, setListFilter] = useState("all"); + const [visible, setVisible] = useState(false); + + const filterMedia = (status) => { + if (status === "all") { + return media; + } + return media.filter((m) => m.name === status); + }; + return ( + <> + + My Lists + + +
+
+
+ user avatar + {user.bannerImage ? ( + image + ) : ( +
+ )} +

{user.name}

+
+
+
+ Created At : + +
+ {sessions && user.name === sessions?.user.name ? ( + + + + + Edit Profile + + ) : null} +
+
+
+ {user.about ? ( +
+ ) : ( + "No description created." + )} +
+
+ +
+
+

+ {user.statistics.anime.episodesWatched} +

+

Total Episodes

+
+
+

+ {user.statistics.anime.count} +

+

Total Anime

+
+ {time?.days ? ( +
+

{time.days}

+

Days Watched

+
+ ) : ( +
+

{time.hours}

+

hours

+
+ )} +
+ {media.length !== 0 && ( +
+
+
+

Lists Filter

+ + + +
+
setVisible(!visible)} + > + + + +
+
+
    +
  • setListFilter("all")} + className={`p-2 cursor-pointer hover:text-action ${ + listFilter === "all" && "bg-secondary text-action" + }`} + > +

    + Show All +

    +
  • + {media.map((item) => ( +
  • setListFilter(item.name)} + className={`cursor-pointer hover:text-action flex gap-2 p-2 duration-200 ${ + item.name === listFilter && "bg-secondary text-action" + }`} + > +

    {item.name}

    +
    + ({item.entries.length}) +
    +
  • + ))} +
+
+ )} +
+ +
+ {media.length !== 0 ? ( + filterMedia(listFilter).map((item, index) => { + return ( +
+

{item.name}

+ + + + + + + + + + {item.entries.map((item) => { + return ( + + + + + + ); + })} + +
+ Title + ScoreProgress
+
+ {item.media.status === "RELEASING" ? ( + + ) : item.media.status === "NOT_YET_RELEASED" ? ( + + ) : ( + + )} + Cover Image +
+ {item.media.id} +
+ + {item.media.title.romaji} + +
+
+ {item.score === 0 ? null : item.score} + + {item.progress === item.media.episodes + ? item.progress + : item.media.episodes === null + ? item.progress + : `${item.progress}/${item.media.episodes}`} +
+
+ ); + }) + ) : ( +
+ {user.name === sessions?.user.name ? ( +

+ Oops!

Looks like you haven't watch anything yet. +

+ ) : ( +

+ Oops!

It looks like this user haven't watch anything + yet. +

+ )} + + + + + Start Watching + +
+ )} +
+
+ + ); +} + +export async function getServerSideProps(context) { + const session = await getServerSession(context.req, context.res, authOptions); + const query = context.query; + + const response = await fetch("https://graphql.anilist.co/", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + query: ` + query ($username: String, $status: MediaListStatus) { + MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { + user { + id + name + about (asHtml: true) + createdAt + avatar { + large + } + statistics { + anime { + count + episodesWatched + meanScore + minutesWatched + } + } + bannerImage + mediaListOptions { + animeList { + sectionOrder + } + } + } + lists { + status + name + entries { + id + mediaId + status + progress + score + media { + id + status + title { + english + romaji + } + episodes + coverImage { + large + } + } + } + } + } + } + `, + variables: { + username: query.user, + }, + }), + }); + + const data = await response.json(); + + const get = data.data.MediaListCollection; + const sectionOrder = get?.user.mediaListOptions.animeList.sectionOrder; + + if (!sectionOrder) { + return { + notFound: true, + }; + } + + const prog = get.lists; + + function getIndex(status) { + const index = sectionOrder.indexOf(status); + return index === -1 ? sectionOrder.length : index; + } + + prog.sort((a, b) => getIndex(a.name) - getIndex(b.name)); + + const user = get.user; + + const time = convertMinutesToDays(user.statistics.anime.minutesWatched); + + return { + props: { + media: prog, + sessions: session, + user: user, + time: time, + }, + }; +} + +function UnixTimeConverter({ unixTime }) { + const date = new Date(unixTime * 1000); // multiply by 1000 to convert to milliseconds + const formattedDate = date.toISOString().slice(0, 10); // format date to YYYY-MM-DD + + return

{formattedDate}

; +} + +function convertMinutesToDays(minutes) { + const hours = minutes / 60; + const days = hours / 24; + + if (days >= 1) { + return days % 1 === 0 + ? { days: `${parseInt(days)}` } + : { days: `${days.toFixed(1)}` }; + } else { + return hours % 1 === 0 + ? { hours: `${parseInt(hours)}` } + : { hours: `${hours.toFixed(1)}` }; + } +} -- cgit v1.2.3